home *** CD-ROM | disk | FTP | other *** search
-
- page ,132
- title Unique - a UNIX-like filter
-
- STDIN equ 0
- STDOUT equ 1
- STDERR equ 2
- CR equ 0dh
- LF equ 0ah
- CPMEOF equ 1ah
-
- Cseg Segment
- Assume CS:Cseg,DS:Cseg,ES:Cseg,SS:Cseg
-
- Org 80h
- Inline Label Byte
- db 128 Dup (?)
-
- Unique Proc Far
- jmp Start
-
- ; message text and data area
- Header db CR,LF,'Unique - Version 1.0 - 24 Feb 1985'
- db CR,LF,' by Ray L. McVay'
- db CR,LF,' 908 Newton'
- db CR,LF,' Arlington, TX 76010'
- db CR,LF,' CompuServe [75006,2563]',CR,LF,CPMEOF
-
- Inlen dw 0
- Outlen dw 0
-
- Start:
- mov AX,offset Outline
- add AX,256
- mov SP,AX ; We're going to shrink up later.
- mov AH,30h ;get DOS version
- int 21h
- cmp AL,2
- jae VerOK
- int 20h ; old exit
-
- VerOK:
- mov BX,SP ; SP = top of needed ram
- mov CL,4
- sar BX,CL ; Divide memory used by 16.
- inc BX ; Round up 1 paragraph (CYA).
- mov AH,4ah ; SETBLOCK
- int 21h ; Assume it worked.
-
- mov BX,STDIN ; get the first line from STDIN
- mov DX,offset Inline
- call Fgets
- mov Inlen,AX
- jnz Uloop
- mov AX,4c01h
- int 21h ; exit(1)
-
- Uloop:
- mov CX,Inlen ; Copy Inline to Outline
- mov Outlen,CX ; first copy the length
- inc CX ; so the EOS will be copied
- mov SI,offset Inline ; then the line
- mov DI,offset Outline
- cld
- rep movsb
-
- Nextline:
- mov BX, STDIN
- mov DX,offset Inline
- call Fgets ; Get next line from STDIN
- mov Inlen,AX
- ; Now compare Inline to Outline
- cmp Outlen,AX ; Unequal lengths can't match!
- jne NotSame
- mov CX,AX ; The lengths are equal so we'll
- mov SI,offset Inline ; compare the strings.
- mov DI,offset Outline
- repe cmpsb
- or CX,CX ; If CX=0 then Inline=Outline
- je Nextline
-
- NotSame:
- mov BX,STDOUT
- mov DX,offset Outline
- call Fputs
- test Inlen,-1 ; Did we hit end of file?
- jnz Uloop ; No. Get next line.
-
- mov AX,4c00h
- int 21h ; exit(0)
-
- ; Get a linefeed terminated string into the buffer pointed to
- ; by DS:DX from the file whose handle is in BX. Make it an ASCIIZ
- ; string and return the length in AX. Return 0 (and ZF) on End of File.
-
- Fgets Proc Near
-
- push SI ; Save the working registers.
- push CX
- push DX
- mov SI,DX ; For easy addressability in the loop.
- NextChar:
- mov CX,1 ; Read one character at a time.
- mov AH,3fh
- int 21h
- dec AX ; AX should be 1 so the dec will make
- jnz HitEnd ; it 0 unless end of file was found.
- cmp byte ptr [SI],LF
- je GotLF
- inc DX
- inc SI
- jmp NextChar
- GotLF:
- inc SI ; Point to byte following the LF.
- mov byte ptr [SI],0 ; Make it EOS ala UNIX.
- pop DX
- sub SI,DX ; length = start of buffer - SI
- mov AX,SI
- jmp short XFgets
- HitEnd:
- sub AX,AX ; Discard last line if it's a partial
- pop DX
- XFgets:
- pop CX ; Restore working registers
- pop SI
- ret
- Fgets endp
-
- ; Send an ASCIIZ string pointed to by DX to the file whose
- ; handle is in BX. Returns status in AX.
-
- Fputs Proc Near
-
- push CX
- push DI
- mov DI,DX ; Calculate the length of the string
- sub AX,AX ; by scanning for the null at the end.
- mov CX,-1 ; Set maximum repeat count.
- repne scasb ; DI will then point 1 byte past EOS null
- sub DI,DX ; so DI-DX-1 should equal the length.
- mov CX,DI
- dec CX
- mov AH,40h
- int 21h
- pop DI
- pop CX
- ret
- Fputs endp
-
- Unique endp
-
- ; Output line buffer is placed here so it won't
- ; eat up a lot of space in the COM file.
-
- Outline label byte ; 128 byte output line buffer.
- ; 128 byte local stack follows.
- Cseg ends
- end Unique